package com.feicheng.common.mqtt;

import com.alibaba.fastjson.JSONObject;
import com.feicheng.common.exception.SystemException;
import com.feicheng.common.task.Cache;
import com.feicheng.persistence.entity.Amenjin;
import com.feicheng.persistence.service.IAclientbmService;
import com.feicheng.persistence.service.IAkechengskjlService;
import com.feicheng.persistence.service.IAmenjinService;
import com.feicheng.service.a.FDzService;
import com.feicheng.service.a.FJlService;
import com.feicheng.service.a.FMjService;
import com.feicheng.service.a.FXyService;
import com.feicheng.service.impl.FMjConnectionService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.List;

@Slf4j
@Component
public class MqttClientCallBack implements MqttCallback {

    @Autowired
    Cache cache;

    @Autowired
    FMjService mjService;

    @Autowired
    IAclientbmService bmService;

    @Autowired
    IAkechengskjlService skjlService;

    @Autowired
    MqttOutboundChannel mqttOutboundChannel;

    @Autowired
    FXyService xyService;

    @Autowired
    FJlService jlService;

    @Autowired
    FDzService dzService;

    @Autowired
    IAmenjinService menjinService;

    @Autowired
    FMjConnectionService mjconnectionService;

    private MyMqttAsyncClient client;

    public void setClient(MyMqttAsyncClient client) {
        this.client = client;
    }


    public void addTopic(String topic) {
        try {
            client.subscribe(topic, 1);
        } catch (Exception e) {
            log.error("添加订阅频道失败", e);
        }
    }

    public void removeTopic(String topic) {
        try {
            client.unsubscribe(topic);
        } catch (Exception e) {
            log.error("添加订阅频道失败", e);
        }
    }

    @Override
    public void connectionLost(Throwable throwable) {
        log.error("mqtt已经断开连接", throwable);
        try {
            this.client.connect();
        } catch (MqttException e) {
            log.error("重连出现问题", e);
        }
    }

    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {

        try {
            log.info("topic:"+topic);
            String kk = new String(mqttMessage.getPayload());
            log.info("内容："+kk);
            JSONObject msg = JSONObject.parseObject(kk);

            if (topic.endsWith("Ack")) {
                if (msg.getString("operator").equals("DeleteAllPerson-Ack")) {
                    JSONObject info = msg.getJSONObject("info");
                    String result = info.getString("result");
                    String sn = info.getString("facesluiceId");
                    if ("ok".equals(result)) {
//                        mjconnectionService.clearMenjinCallBack(sn);
                        log.info(sn+"号门禁清空人员成功。");
                    } else if ("fail".equals(result)) {
                        // 清空门禁所有人员信息失败的情况下，从新下达清空门禁所有人员指令。
                        log.info(sn+"号门禁清空人员失败。即将发起重新清空指令。");
                        mjconnectionService.cmdDeleteAllPerson(sn);
                    }
                }
            }

            if (topic.endsWith("Rec")) {
                if (msg.getString("operator").equals("RecPush")) {
                    JSONObject info = msg.getJSONObject("info");
                    String customId = info.getString("customId");
                    customId = MqttCmd.IDS.get(customId);

                    String sn = info.getString("facesluiceId");
                    if (!StringUtils.hasLength(customId)) {
                        log.warn(sn+"设备无法找到customId");
                        return;
                    }

                    /**
                     * VerifyStatus
                     * 0: 无
                     * 1: 允许
                     * 2: 拒绝
                     * 3: 还没有注册
                     * 22:待核验(开门方式为 3:人脸核验+远程开门方式的控制记录)
                     * 24:无权限（特殊版本非通行时间段的控制记录）
                     */
                    Integer verifyStatus = info.getInteger("VerifyStatus");

                    /**
                     * PersonType
                     * 0: 白名单
                     * 1: 黑名单
                     */
                    Integer personType = info.getInteger("PersonType");

                    /**
                     * 1: 白名单验证
                     * 2: 身份证验证
                     * 3: 白名单 + 身份证验证
                     * 7: MQTT 远程开门
                     * 21:RF 卡验证(内置刷卡机型)
                     * 22:RF 卡验证 + 白名单验证(内置刷卡机型)
                     * 24:韦根卡验证
                     * 25:韦根卡 + 白名单验证
                     * 27:HTTP 远程开门
                     */
                    Integer otype = info.getInteger("otype");

                    String time = info.getString("time");

                    if (22 == verifyStatus) {
                        if (customId.startsWith("CLI")) {
                            JSONObject param = new JSONObject();
                            param.put("clientid", customId);
                            param.put("mjid", sn);
                            try {
                                xyService.sl(param);
                                mjconnectionService.cmdUnlock(sn);
                            } catch (SystemException se) {
                                log.error("不开门", se);
                            } catch (Exception e) {
                                log.error("不开门", e);
                            }
                        } else if (customId.startsWith("JL")) {
                            JSONObject param = new JSONObject();
                            param.put("jlid", customId);
                            param.put("mjid", sn);
                            try {
                                jlService.sl(param);
                                mjconnectionService.cmdUnlock(sn);
                            } catch (SystemException se) {
                                log.error("不开门", se);
                            } catch (Exception e) {
                                log.error("不开门", e);
                            }
                        } else if (customId.startsWith("DZ")) {
                            JSONObject param = new JSONObject();
                            param.put("dzid", customId);
                            param.put("mjid", sn);
                            try {
                                dzService.sl(param);
                                mjconnectionService.cmdUnlock(sn);
                            } catch (SystemException se) {
                                log.error("不开门", se);
                            } catch (Exception e) {
                                log.error("不开门", e);
                            }
                        } else if (customId.startsWith("MDJL")) {
                            JSONObject param = new JSONObject();
                            param.put("mdjlid", customId);
                            param.put("mjid", sn);
                            try {
                                dzService.mdjlsl(param);
                                mjconnectionService.cmdUnlock(sn);
                            } catch (SystemException se) {
                                log.error("不开门", se);
                            } catch (Exception e) {
                                log.error("不开门", e);
                            }
                        }
                    }



                }
            }


            if ("mqtt/face/basic".equals(topic)) {
                if (msg.getString("operator").equals("Online")) {
                    JSONObject info = msg.getJSONObject("info");
                    String sn = info.getString("facesluiceId");
                    try {
                        dzService.menjinHeartBeat(sn, true);
                        if (null == cache.getMenjin(sn)) {
                            JSONObject mj = mjService.getMenjinBySn(sn);
                            if (mj != null) {
                                cache.putMenjin(mj);
                                String totopic = "mqtt/face/"+sn;
                                this.addTopic("mqtt/face/"+sn+"/Ack"); // 订阅设备响应频道
                                this.addTopic("mqtt/face/"+sn+"/Rec"); // 订阅设备认证人员扫脸上传频道
                                this.addTopic("mqtt/face/"+sn+"/Snap"); // 订阅设备陌生人扫脸上传频道
                                this.addTopic("mqtt/face/"+sn+"/QRCode"); // 订阅设备二维码扫码上传频道
                                JSONObject res = MsgFactory.onlineAck(msg.getString("MessageId"));
                                mqttOutboundChannel.publish(1, false, totopic, res.toJSONString());
                                mjconnectionService.addFaceToMenjin(sn);
                            } else {
                                log.error(sn+"设备尚未启用，无法完成上线注册");
                            }
                        } else {
                            String totopic = "mqtt/face/"+sn;
                            this.addTopic("mqtt/face/"+sn+"/Ack"); // 订阅设备响应频道
                            this.addTopic("mqtt/face/"+sn+"/Rec"); // 订阅设备认证人员扫脸上传频道
                            this.addTopic("mqtt/face/"+sn+"/Snap"); // 订阅设备陌生人扫脸上传频道
                            this.addTopic("mqtt/face/"+sn+"/QRCode"); // 订阅设备二维码扫码上传频道
                            JSONObject res = MsgFactory.onlineAck(msg.getString("MessageId"));
                            mqttOutboundChannel.publish(1, false, totopic, res.toJSONString());
                            mjconnectionService.addFaceToMenjin(sn);
                        }
                    } catch (Exception e) {
                        log.error("设备上线更新出现问题", e);
                    }
                } else if (msg.getString("operator").equals("Offline")) {
                    JSONObject info = msg.getJSONObject("info");
                    String sn = info.getString("facesluiceId");
                    try {
                        dzService.menjinHeartBeat(sn, false);
                        cache.removeMenjin(sn);
                        this.removeTopic("mqtt/face/"+sn+"/Ack"); // 订阅设备响应频道
                        this.removeTopic("mqtt/face/"+sn+"/Rec"); // 订阅设备认证人员扫脸上传频道
                        this.removeTopic("mqtt/face/"+sn+"/Snap"); // 订阅设备陌生人扫脸上传频道
                        this.removeTopic("mqtt/face/"+sn+"/QRCode"); // 订阅设备二维码扫码上传频道
                    } catch (Exception e) {
                        log.error("设备下线更新出现问题", e);
                    }
                }
            } else if ("mqtt/face/heartbeat".equals(topic)) {
                if (msg.getString("operator").equals("HeartBeat")) {
                    JSONObject info = msg.getJSONObject("info");
                    String sn = info.getString("facesluiceId");

                    if (null == cache.getMenjin(sn)) {
                        try {
                            dzService.menjinHeartBeat(sn, true);
                            JSONObject mj = mjService.getMenjinBySn(sn);
                            if (mj != null) {
                                cache.putMenjin(mj);
                                this.addTopic("mqtt/face/"+sn+"/Ack"); // 订阅设备响应频道
                                this.addTopic("mqtt/face/"+sn+"/Rec"); // 订阅设备认证人员扫脸上传频道
                                this.addTopic("mqtt/face/"+sn+"/Snap"); // 订阅设备陌生人扫脸上传频道
                                this.addTopic("mqtt/face/"+sn+"/QRCode"); // 订阅设备二维码扫码上传频道
                                mjconnectionService.addFaceToMenjin(sn);
                            } else {
                                log.error(sn+"设备尚未注册，无法启用。");
                            }
                        } catch (Exception e) {
                            log.error("设备心跳更新出现问题", e);
                        }
                    } else {
                        JSONObject mj = cache.getMenjin(sn);
                        StringBuilder loginfo = new StringBuilder().append("门店【").append(mj.getString("sname")).append("|").append(mj.getString("storeid")).append("】");
                        if (StringUtils.hasLength(mj.getString("rname"))) {
                            loginfo.append("-房间【").append(mj.getString("rname")).append("|").append(mj.getString("roomid")).append("】");
                        }
                        loginfo.append("-设备【").append(sn).append("】跟踪正常！心跳信号正常！");
                        log.info(loginfo.toString());
                    }


                }
            }
        } catch (Exception e) {
            log.error("err",e);
        }

    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        log.info("发布消息成功");
    }
}
